package com.todo.pro.controller;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.todo.pro.entity.SystemMenu;
import com.todo.pro.handle.EE;
import com.todo.pro.jwt.JwtUtil;
import com.todo.pro.res.JsonResult;
import com.todo.pro.res.model.SystemMenuResult;
import com.todo.pro.service.SystemMenuService;
import com.todo.pro.util.MapUtil;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.NumberUtil;

/**
 * @author SiZhongxia
 * @since 2017-12-27
 */
@Controller
@RequestMapping("menu")
public class MenuController extends BaseController {

	private Logger logger = LoggerFactory.getLogger(MenuController.class);

	@Autowired
	private SystemMenuService systemMenuService;

	@RequiresAuthentication
	@RequestMapping(value = "list")
	public ModelAndView list(HttpServletRequest request) {
		ModelAndView mav = new ModelAndView("modules/menu/list");
		mav.addObject("csrftoken",
				JwtUtil.createToken(MapUtil.init().putVal("path", "gq-menu-list"), 2L * 60 * 60 * 1000));
		return mav;
	}

	@ResponseBody
	@RequiresAuthentication
	@RequestMapping(value = "data")
	public JsonResult<List<SystemMenuResult>> data(HttpServletRequest request) {

		Wrapper<SystemMenu> menuWrapper = new EntityWrapper<>();
		menuWrapper.orderBy("used", false).orderBy("pid", true).orderBy("sort_num", false);
		List<SystemMenu> menus = systemMenuService.selectList(menuWrapper);

		List<SystemMenuResult> menurs = new ArrayList<>();
		int count = menus.size();
		if (count > 0) {
			for (SystemMenu menu : menus) {
				SystemMenuResult menur = new SystemMenuResult();
				BeanUtils.copyProperties(menu, menur);
				menur.setId(menu.getId().toString());
				menur.setPid(menu.getPid().toString());
				menurs.add(menur);
			}
		}

		return new JsonResult<List<SystemMenuResult>>(count, menurs);
	}

	@ResponseBody
	@RequiresAuthentication
	@RequestMapping(value = "changeusedstatus")
	public JsonResult<Object> changeusedstatus(HttpServletRequest request) {
		String menuId = request.getParameter("menuId");
		if (StringUtils.isBlank(menuId)) {
			return new JsonResult<Object>(false, EE.INVALID_PARAMETERS.i());
		}
		String used = request.getParameter("used");
		if (!NumberUtil.isInteger(used)) {
			return new JsonResult<Object>(false, EE.INVALID_PARAMETERS.i());
		}

		SystemMenu systemMenu = systemMenuService.selectById(menuId);
		if (systemMenu == null) {
			return new JsonResult<Object>(false, EE.INVALID_PARAMETERS.i());
		}
		if (systemMenu.getPid() == -1 && new Integer(used) == 0) {
			Wrapper<SystemMenu> systemMenuWrapper = new EntityWrapper<>();
			systemMenuWrapper.eq("pid", systemMenu.getId()).eq("used", 1);
			List<SystemMenu> childs = systemMenuService.selectList(systemMenuWrapper);
			if (childs != null && childs.size() > 0) {
				for (SystemMenu item : childs) {
					item.setUsed(new Integer(used));
					item.setUpdateTime(DateUtil.date());
				}
				if (!systemMenuService.updateBatchById(childs)) {
					return new JsonResult<Object>(false, EE.ERR_FOR_WAIT.i());
				}
			}
		}
		systemMenu.setUsed(new Integer(used));
		systemMenu.setUpdateTime(DateUtil.date());
		if (!systemMenuService.updateById(systemMenu)) {
			return new JsonResult<Object>(false, EE.ERR_FOR_WAIT.i());
		}

		return new JsonResult<Object>(true, EE.SUCCESS_OP.i());
	}

	@ResponseBody
	@RequiresAuthentication
	@RequestMapping(value = "updateField")
	public JsonResult<Object> updateField(HttpServletRequest request) {
		String csrftoken = request.getParameter("csrftoken");
		if (StringUtils.isBlank(csrftoken)) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}
		Map<String, Object> jwtData = JwtUtil.parseJWT(csrftoken);
		if (jwtData == null) {
			return new JsonResult<Object>(false, EE.ERROR_FORM_OVERDUE.i());
		}

		if (!"gq-menu-list".equals(jwtData.get("path"))) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}

		String id = request.getParameter("id");
		if (StringUtils.isBlank(id)) {
			return new JsonResult<Object>(false, EE.INVALID_PARAMETERS.i());
		}

		String field = request.getParameter("field");
		if (StringUtils.isBlank(field)) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}

		String value = request.getParameter("value");
		if (StringUtils.isBlank(value)) {
			value = "";
		}

		SystemMenu systemMenu = systemMenuService.selectById(id);
		if (systemMenu == null) {
			return new JsonResult<Object>(false, EE.INVALID_PARAMETERS.i());
		}
		if ("name".equals(field)) {
			systemMenu.setName(value);
		} else if ("icon".equals(field)) {
			systemMenu.setIcon(value);
		} else if ("url".equals(field)) {
			systemMenu.setUrl(value);
		} else if ("path".equals(field)) {
			systemMenu.setPath(value);
		} else if ("sortNum".equals(field)) {
			systemMenu.setSortNum(new Integer(value));
		} else {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}
		systemMenu.setUpdateTime(DateUtil.date());
		if (!systemMenuService.updateById(systemMenu)) {
			return new JsonResult<Object>(false, EE.ERR_FOR_WAIT.i());
		}

		return new JsonResult<Object>(true, EE.SUCCESS_OP.i());
	}

	@RequiresAuthentication
	@RequestMapping(value = "add")
	public ModelAndView add(HttpServletRequest request) {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("modules/menu/add");
		mav.addObject("pid", request.getParameter("pid"));
		mav.addObject("csrftoken", JwtUtil.createToken(MapUtil.init().putVal("path", "gq-menu-add"), 30L * 60 * 1000));
		return mav;
	}

	@ResponseBody
	@RequiresAuthentication
	@RequestMapping(value = "save")
	public JsonResult<Object> save(HttpServletRequest request) {
		String csrftoken = request.getParameter("csrftoken");
		if (StringUtils.isBlank(csrftoken)) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}
		Map<String, Object> jwtData = JwtUtil.parseJWT(csrftoken);
		if (jwtData == null) {
			return new JsonResult<Object>(false, EE.ERROR_FORM_OVERDUE.i());
		}

		if (!"gq-menu-add".equals(jwtData.get("path"))) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}
		String pid = request.getParameter("pid");
		if (StringUtils.isBlank(pid)) {
			pid = "-1";
		}
		String name = request.getParameter("name");
		if (StringUtils.isBlank(name)) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}

		String icon = request.getParameter("icon");
		if (StringUtils.isBlank(icon)) {
			icon = "layui-icon-set";
		}

		String url = request.getParameter("url");
		if (StringUtils.isBlank(url)) {
			url = "javascript:;";
		}
		String path = request.getParameter("path");
		if (StringUtils.isBlank(path)) {
			path = "";
		}
		SystemMenu systemMenu = new SystemMenu();
		systemMenu.setPid(new Long(pid));
		systemMenu.setName(name);
		systemMenu.setIcon(icon);
		systemMenu.setUrl(url);
		systemMenu.setPath(path);
		systemMenu.setUsed(0);
		systemMenu.setSortNum(0);
		systemMenu.setCreateTime(DateUtil.date());
		systemMenu.setUpdateTime(DateUtil.date());
		if (!systemMenuService.insert(systemMenu)) {
			return new JsonResult<Object>(false, EE.ERR_FOR_WAIT.i());
		}

		return new JsonResult<Object>(true, EE.SUCCESS_OP.i());
	}

	@ResponseBody
	@RequiresAuthentication
	@RequestMapping(value = "delete")
	public JsonResult<Object> delete(HttpServletRequest request) {
		String csrftoken = request.getParameter("csrftoken");
		if (StringUtils.isBlank(csrftoken)) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}
		Map<String, Object> jwtData = JwtUtil.parseJWT(csrftoken);
		if (jwtData == null) {
			return new JsonResult<Object>(false, EE.ERROR_FORM_OVERDUE.i());
		}

		if (!"gq-menu-list".equals(jwtData.get("path"))) {
			return new JsonResult<Object>(false, EE.ERROR_FORM.i());
		}

		String[] ids = request.getParameterValues("ids[]");
		if (ids == null || ids.length == 0) {
			return new JsonResult<Object>(false, EE.SELECT_LEAST_ONE_RECORD.i());
		}

		Set<Long> deleteMenuIds = new HashSet<>();
		for (String menuId : ids) {
			deleteMenuIds.add(new Long(menuId));
			SystemMenu item = systemMenuService.selectById(new Long(menuId));
			if (item == null) {
				return new JsonResult<Object>(false, EE.ERROR_FORM.i());
			}
		}

		for (Long menuId : deleteMenuIds) {
			Wrapper<SystemMenu> systemMenuWrapper = new EntityWrapper<>();
			systemMenuWrapper.eq("pid", menuId);
			List<SystemMenu> childs = systemMenuService.selectList(systemMenuWrapper);
			if (childs != null && childs.size() > 0) {
				boolean notExist = false;
				for (SystemMenu c : childs) {
					if (!deleteMenuIds.contains(c.getId())) {
						notExist = true;
						break;
					}
				}
				if (notExist) {
					return new JsonResult<Object>(false, EE.DELETE_EXSIT_CHILDS.i());
				}
			}
		}

		if (!systemMenuService.deleteBatchIds(deleteMenuIds)) {
			return new JsonResult<Object>(false, EE.ERR_FOR_WAIT.i());
		}

		return new JsonResult<Object>(true, EE.SUCCESS_OP.i());
	}

}
